#!/usr/bin/python
"""
 * liblwbtAPI.py - basic python interface to liblwbt.so for testing purposes
 * (C) 2008 by Michael Kramer <kramtek@gmail.com>
 *
"""

import sys
import time
import threading
import time

from ctypes import *

# Load lwbt library
liblwbt = CDLL("./lib/liblwbt.so", RTLD_GLOBAL);

#
# Create python wrappers around library functions 
#

# Get the library ready before it can be used 
def setup_library() :
    print "setting up lwbtlib..."
    liblwbt.lib_init()
    liblwbt.lib_setup()
    print "liblwbt ready for operation\n"
    

def shutdown_library() :
    print "Shutting down library..."
    liblwbt.lib_shutdown()

# Get the local mac addr and device name
def get_local_mac_addr() :
    addr = c_char_p("none yet")
    liblwbt.get_local_mac_addr(byref(addr))
    return addr.value

def get_local_name() :
    name = c_char_p("none yet")
    liblwbt.get_local_name(byref(name))
    return name.value

def set_local_name(name="temporary") :
    charname = c_char_p(name)
    liblwbt.set_local_name(byref(charname), len(name))

# Scan for discoverable devices 
def scan(scan_time=10) :
    print "calling liblwbt.hci_scan() ...."
    scan_results = c_char_p("none yet")
    numDevices = liblwbt.hci_scan(byref(scan_results), scan_time, 0)
    scan_results = scan_results.value
    print "  Found %d devices" % numDevices
    availDevices = []
    deviceCODs = []
    bdaddr = (c_byte * 6)()
    name = c_char_p("none yet")
    if (numDevices > 0) :
        for index in range(numDevices) :
            availDevices.append(scan_results[(1+index*25):((index+1)*25-7)])
            deviceCODs.append(scan_results[(1+index*25+18):((index+1)*25)])
            print "     #%d: %s      COD: %s" % ((index+1), availDevices[index], deviceCODs[index])
            #bt_addr = availDevices[index]
            #for index2 in range(6) :
            #    bdaddr[index2] = int(bt_addr[0:2], 16)
            #    bt_addr = bt_addr[3:len(bt_addr)]

            #liblwbt.get_device_name(bdaddr, byref(name))
            #print "     #%d: %s\n         %s      COD: %s" % ((index+1), name.value, availDevices[index], deviceCODs[index])

    return availDevices

# Start RFCOMM fifo server for i/o (should be started in separate thread, see rfcomm_connect) 
def rfcomm_fifo_serve() :
    print "\n  starting rfcomm i/o via fifo server ...\n"
    liblwbt.connect_dev_io()
    print "   shutting down the connection.\n\n" 
    print "Shutting down the library..."
    shutdown_library()

# Initiate RFCOMM connection with specified device
def rfcomm_connect(bt_addr=None, pin_code="1234", start_fifo=1 ) :
    bdaddr = (c_byte * 6)()

    if (bt_addr == None) :
        return 0
        
    print "connecting to %s   with pin = %s " % (bt_addr, pin_code)

    for index in range(6) :
        bdaddr[index] = int(bt_addr[0:2], 16)
        bt_addr = bt_addr[3:len(bt_addr)]

    response = liblwbt.connect_rfcomm(bdaddr, 1)

    if (response == 10) :
        # Need to request pin code from user  
        raw_pin= pin_code 
        pin = c_char_p(raw_pin)
        print "sending %s as the pin-code ..." % raw_pin
        response = liblwbt.connect_pin_req(pin, len(raw_pin))
    
    if (response == 6) :
        print "   connection successful!" 
        if (start_fifo == 1) :
            # Start the rfcomm fifo server in a separate thread
            print "trying to start thread for i/o??"
            t = threading.Timer(0.1, rfcomm_fifo_serve)
            t.start()
            time.sleep(1)
            
    if (response == 5) :
        print "   connection error: device refused connection"
    if (response == 4) :
        print "   connection error: cannot find SP support on selected device"
    if (response == 3) :
        print "   connection error: no viable sdp record returned"
    if (response == 2) :
        print "   connection error: could not connect to device"

    return response

# Hold in wait loop to demo serving sdp records
def sdp_serv() :
    liblwbt.hci_monitor(0)
    print "going into waiting loop to serve sdp records... (ctrl+c to quit)"
    for index in range(200) :
        time.sleep(0.1)
        #time.sleep(1.4)
        liblwbt.check_input(9) 

#
# Make sure library is initialized and setup before using it
#
setup_library()
set_local_name("Homer")


